<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="google-site-verification" content="yaeorbXgKPwp5BDegBtAJEHYWFEFE-BViWTj74gJPrw" />
<!--  -->
<link href="/css/default.css" type="text/css" rel="stylesheet" />
<!--  -->
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/lang/en.js"></script>
<script type="text/javascript" src="/js/mac/core.min.js"></script>
<title>mac-message 消息组件 —— 基础示例</title>
<meta name="description" content="mac-message activemq jms broker 消息中间件 消息中心" />
<meta name="keywords" content="mac-message activemq jms broker 消息中间件 消息中心 消息监控" />
<script type="text/javascript">
$(function(){
	function adjust(){
		var de = document.documentElement
			, ch = de.clientHeight, cw = de.clientWidth;
		$('#body').width(cw - 16);
	}
	$(window).resize(adjust);
	adjust();
});
</script>
</head>
<body>
<div id="head">
	<a href="/en/"><img src="/css/images/logo_s.png" alt="logo" /></a>
	<div class="title">BOARSOFT.COM</div>
	<div class="right">
		<div>
			<a href="/public/lang.php?l=en">English</a>
			|
			<a href="/public/lang.php?l=cn">简体中文</a>
			|
			<a href="http://activemq.apache.org/" target="_blank">ActiveMQ</a>
			|
			<a href="https://redis.io/" target="_blank">Redis</a>
			|
			<a href="http://www.jquery.com/" target="_blank">JQuery</a>
		</div>
	</div>
</div><div id="body">
	<div class="dir">
<h1>目录</h1>
<hr/>
<ul>
	<li><a href="./index.html">基本概念</a></li>
	<ul>
		<li><a href="./index.html#queue">消息队列与发件人队列</a></li>
		<li><a href="./index.html#adapter">输入输出适配器</a></li>
		<li><a href="./index.html#finder">过滤与分拣插件</a></li>
		<li><a href="./index.html#tq">目标队列</a></li>
		<li><a href="./index.html#rq">收件人队列</a></li>
		<li><a href="./index.html#converter">消息转换器</a></li>
		<li><a href="./index.html#finder">滤与分拣插件</a></li>
		<li><a href="./index.html#ack">收件人消息签收</a></li>
	</ul>
	<li><a href="./config.html">配置项</a></li>
	<ul>
		<li><a href="./config.html">基本配置</a></li>
		<li><a href="./config.html#queues">外置队列信息配置</a></li>
		<li><a href="./config.html#amqServer">服务端ActiveMQ配置</a></li>
		<li><a href="./config.html#amqClient">客户端ActiveMQ长连接配置</a></li>
	</ul>
	<li><a href="./demo.html">用法示例</a></li>
	<ul>
		<li><a href="./demo.html#rpc">基于RPC的收发</a></li>
		<li><a href="./demo.html#amq">ActiveMQ/JMS的收发</a></li>
		<li><a href="./demo.html#adapter">输入输出适配器</a></li>
		<li><a href="./demo.html#converter">消息转换器</a></li>
		<li><a href="./demo.html#finder">过滤与分拣插件</a></li>
		<li><a href="./demo.html#shard">简单水平分片</a></li>
	</ul>
	<li><a href="./monitor.html">可视化消息监控</a></li>
	<ul>
		<li><a href="./monitor.html">功能介绍</a></li>
	</ul>
	<li><a href="./advance.html">进阶应用</a></li>
	<ul>
		<li><a href="./advance.html#ack">收件人消息签收</a></li>
		<li><a href="./advance.html#converter">自定义消息转换器</a></li>
		<li><a href="./advance.html#interceptor">ActiveMQ消息拦截与转换</a></li>
		<li><a href="./advance.html#ack">收件人消息签收</li>
		<li><a href="./advance.html#finder">过滤与分拣插件</a></li>
		<li><a href="./advnace.html#shard">使用数据库中间件</a></li>
	</ul>
</ul>	</div>
	<div class="main">
		<div id="nav">
			<div id="nav_path">
				<a href="/en/">Home</a>
				&gt;
				<a href="/en/mac/message">mac-message</a>
				&gt;
				示例
			</div>
			<div id="nav_back">
				<a href="javascript:history.back()">Back</a>
				|
				<a href="/en/">UP</a> &nbsp;&nbsp;
			</div>
			<div class="clear"></div>
		</div>
<h1>mac-message - 示例</h1>
点击下载&nbsp;<a href="/mac/message/dl/message_demo.rar">消息应用示例</a>
｜
<a href="/mac/message/dl/message_server1.rar">简化版消息中间件</a>
｜
<a href="/mac/message/dl/message_web.rar">简化版消息管控</a>
｜
<a href="/en/download.html">依赖JAR包与源码下载</a>
<h2><a name="rpc"></a>基于RPC的收发</h2>
&nbsp;&nbsp;生产者：queues.xml
<xmp>
	<bean id="targetQueueMap" class="java.util.HashMap">
		<constructor-arg>
			<map>
				<entry key="queue1">
					<bean class="com.boarsoft.message.bean.TargetMQ">
						<property name="catalog" value="demo" />
						<property name="code" value="queue1" />
					</bean>
				</entry>
			</map>
		</constructor-arg>  
	</bean>
</xmp>
&nbsp;&nbsp;生产者：consume.xml
<xmp>
	<reference id="serverMsgSvc" group="message" name="server"
		interface="com.boarsoft.message.core.MessageService"
		version="1.0.0" timeout="3000">
	</reference>
</xmp>
&nbsp;&nbsp;生产者： RpcPubTest.java
<xmp>
	Message m = new Message();
	m.setTarget("queue1");
	m.setContent("Hello world!");
	m.setId(RandomUtil.genUUID());
	m.addRecipient("queue1Consumer1");
	log.info("Send message {}", m);
	// 此时，注入给Messenger的是localMsgSvc1则不是amqClient1
	Messenger.send(m);
</xmp>
&nbsp;&nbsp;中间件：queues.xml
<xmp>
	<bean id="targetQueueMap" class="java.util.HashMap">
		<constructor-arg>
			<map>
				<entry key="queue1">
					<bean class="com.boarsoft.message.bean.TargetMQ">
						<property name="catalog" value="demo" />
						<property name="code" value="queue1" />
					</bean>
				</entry>
			</map>
		</constructor-arg>  
	</bean>
</xmp>
&nbsp;&nbsp;中间件：consumer.xml
<xmp>
	<reference id="queue1Consumer1" group="message" name="queue1Consumer1"
		interface="com.boarsoft.message.core.MessageService" version="1.0.0"
		timeout="12000" type="SN">
	</reference>
</xmp>
&nbsp;&nbsp;中间件：provider.xml
<xmp>
	<service ref="localMsgSvc1" group="message" name="server"
		interface="com.boarsoft.message.core.MessageService"
		version="1.0.0" timeout="3000">
	</service>
</xmp>
&nbsp;&nbsp;消费者：provide.xml
<xmp>
	<service ref="queue1Consumer1" group="message" name="queue1Consumer1"
		interface="com.boarsoft.message.core.MessageService" type="SN"
		version="1.0.0" timeout="12000">
	</service>
</xmp>
&nbsp;&nbsp;消费者：Queue1Consumer1.java
<xmp>
	@Component("queue1Consumer1")
	public class Queue1Consumer1 implements MessageService {
		private static final Logger log = LoggerFactory.getLogger(Queue1Consumer1.class);
	
		@Override
		public void put(Message msg) throws Exception {
			log.info("Received message: {}", JsonUtil.from(msg));
		}
	}
</xmp>
<h2><a name="amq"></a>ActiveMQ/JMS收发</h2>
&nbsp;&nbsp;消费者、生产者、中间件的 queues.xml 与前述基于RPC的方式相同。不再需要 consume.xml 和 provide.xml<br/>
&nbsp;&nbsp;在中间件增加配置文件 activemq.xml，内容如下：
<xmp>
	<broker xmlns="http://activemq.apache.org/schema/core" useJmx="false">
		<transportConnectors>
			<transportConnector uri="amqp://0.0.0.0:5672" />
			<transportConnector uri="tcp://0.0.0.0:61616" />
		</transportConnectors>
		<plugins>
			<discardingDLQBrokerPlugin dropAll="true"
				dropTemporaryTopics="true" dropTemporaryQueues="true" />

			<bean xmlns="http://www.springframework.org/schema/beans"
				class="com.boarsoft.message.amq.plugin.InterceptorPlugin">
				<property name="localMsgSvc1" ref="localMsgSvc1" />
			</bean>
		</plugins>
	</broker>
</xmp>
&nbsp;&nbsp;基于ActiveMQ/JMS可以有多种方式实现消息的收发，这里分别给出短连接和长连接的两个示例。<br/>
&nbsp;&nbsp;短连接方式消息发送： AmqPubTest1.java
<xmp>
	// 可以使用ActiveMQ API来创建连接工厂
	ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
	// 也可以使用JMS API来创建连接工厂
	// JmsConnectionFactory factory = new
	// JmsConnectionFactory("amqp://127.0.0.1:5672");
	// JmsConnectionFactory factory = new
	// JmsConnectionFactory("tcp://127.0.0.1:61616");
	Connection connection = factory.createConnection("admin", "admin");
	// connection.setClientID("demo");
	connection.start();
	final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	Destination destination = session.createQueue("queue1");
	final MessageProducer producer = session.createProducer(destination);
	producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
	try {
		Message m = new Message();
		m.setTarget("queue1");
		m.setContent("Hello world!");
		// 采用ActiveMQ/JMS方式时，是否需要设置收件人，取决于消息者如何处理
		// m.addRecipient("queue1Consumer1");
		m.setId(RandomUtil.genUUID());
		log.info("Send message {}", m);
		TextMessage tm = session.createTextMessage(m.toJson());
		producer.send(tm);
		// ObjectMessage om = session.createObjectMessage(m);
		// producer.send(om);
	} finally {
		connection.close();
	}
</xmp>
&nbsp;&nbsp;长连接方式需要在生产者和消费都都增加 activemq.xml，内容如下：
<xmp>
	<!-- 实现 javax.jms.Message 与 com.boarsoft.message.bean.Message 之间的互转 -->
	<bean id="msgConverter" class="com.boarsoft.message.demo.DemoJmsMsgConverter">
	</bean>

	<bean id="amqClient1" class="com.boarsoft.message.activemq.AmqClientEx">
		<property name="destMap">
			<map>
				<entry key="queue1">
					<bean class="com.boarsoft.boar.gateway.activemq.AmqDestination">
						<property name="producer">
							<bean class="com.boarsoft.message.activemq.AmqProducerEx">
								<property name="converter" ref="msgConverter" />
							</bean>
						</property>
						<property name="consumer">
							<bean class="com.boarsoft.message.activemq.AmqConsumerEx">
								<property name="converter" ref="msgConverter" />
								<property name="handler" ref="queue1Consumer1" />
							</bean>
						</property>
					</bean>
				</entry>
			</map>
		</property>
		<property name="connectionFactory">
			<bean class="org.apache.activemq.pool.PooledConnectionFactory">
				<property name="maxConnections" value="10" />
				<property name="connectionFactory">
					<bean class="org.apache.activemq.ActiveMQConnectionFactory">
						<property name="brokerURL"
							value="failover:(tcp://localhost:61616,tcp://127.0.0.1:61616)?randomize=true" />
						<property name="userName" value="admin" />
						<property name="password" value="admin" />
					</bean>
				</property>
			</bean>
		</property>
	</bean>
</xmp>
&nbsp;&nbsp;长连接方式消息发送： AmqPubTest2.java
<xmp>
	final MessageService client = (MessageService) ctx.getBean("amqClient1");
	Message m = new Message();
	m.setTarget("queue1");
	m.setContent("Hello world!");
	m.setId(RandomUtil.genUUID());
	client.put(m);
</xmp>
	</div>
</div>
<div id="foot">
Copyright © 2011. All rights reserved&nbsp;&nbsp;蜀ICP备11014774号-1&nbsp;&nbsp;
QQ: 7213571&nbsp;&nbsp;E-mail: pyh_jerry@163.com&nbsp;&nbsp;
<!-- 
<script type="text/javascript">
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3Ffc0b0282216be3d16055855d8c0e72d9' type='text/javascript'%3E%3C/script%3E"));
</script>
&nbsp;&nbsp;
 -->
</div></body>
</html>
